/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.model.seqs;

import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Longs;
import org.zhiqim.kernel.util.Strings;

/**
 * 整型序列值，默认从1从0x7FFFFFFF(最大值)<br><br>
 * 1、支持指定len/max两种方式来指定最大值，注意max时使用长整型，如999L，999表示长度<br>
 * 2、注意：本类不会验证min/max/len/seq四值在初始化时的值问题，要谨慎使用
 * 
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class Sequence
{
    //最小最大值必须构造即指定，不支持中途修改
    private final long min;
    private final long max;
    private final int len;
    
    //子类可见，用于子类重写next等
    protected long sequence;
    
    /******************************************************************************/
    //构造函数&设置长度方法
    /******************************************************************************/
    
    /** 从1到0x7FFFFFFF */
    public Sequence()
    {
        this(1, Integer.MAX_VALUE, 10, 1);
    }
    
    /** 从1到len个9 */
    public Sequence(int len)
    {
        this(1, Ints.getMaxInt(len), len, 1);
    }
    
    /** 从min到max */
    public Sequence(long min, long max)
    {
        this(min, max, Longs.length(max), min);
    }
    
    /** 从min到max，指定初始值 */
    public Sequence(long min, long max, long seq)
    {
        this(min, max, Longs.length(max), seq);
    }
    
    /** 绝大多数的情况下不会设置错误，所以没有作验证，防止不明所以的NoClassDefFoundError */
    protected Sequence(long min, long max, int len, long seq)
    {
        this.min = min;
        this.max = max;
        this.len = len;
        
        this.sequence = seq;
        this.init();
    }
    
    /** 构造函数时子类可选重写初始化 */
    protected void init()
    {
    }
    
    /******************************************************************************/
    //公开的next方法
    /******************************************************************************/
    
    /** 下一个长整数 */
    public long next()
    {
        synchronized (this)
        {
            chkSequence();
            return sequence++;
        }
    }
    
    /** 下一个整数 */
    public int nextInt()
    {
        return (int)next();
    }
    
    /** 下一个整数前补0的定长字符串 */
    public String nextString()
    {
        return Strings.prefixZero(next(), len);
    }
    
    /******************************************************************************/
    //当前参数值
    /******************************************************************************/
    
    public long getMin()
    {
        return min;
    }
    
    public long getMax()
    {
        return max;
    }

    public int getLen()
    {
        return len;
    }
    
    public long getSequence()
    {
        return sequence;
    }
    
    /******************************************************************************/
    //子类调用的方法
    /******************************************************************************/
    
    /** 检查序列号是否回归，注意：子类需同步锁 */
    protected void chkSequence()
    {
        if (sequence <= min || sequence > max)
        {//0x7FFFFFFF+1=负数<0，取sequence<=min，其他取sequence>max
            sequence = min;
        }
    }
    
    /** 重置序列号为最小值，注意：子类需同步锁 */
    protected void resetSequence()
    {
        sequence = min;
    }
    
    /** 设置序列号值，一般用于初始化时 */
    protected void setSequence(long seq)
    {
        if (seq < min || seq > max)
            return;
        
        sequence = seq;
    }
}
